package servlets;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import svc.BWSvc;
import svc.CullSvc;
import svc.FileSvc;
import svc.MilkSvc;
import svc.MiscSvc;
import svc.PriceSvc;
import svc.ReproSvc;
import svc.ResultSvc;
import utils.Utility;
import constants.Constants;
import domain.bw.BodyWeightOpen;
import domain.cull.Cull;
import domain.file.FileDetails;
import domain.milk.Milk;
import domain.misc.Misc;
import domain.price.Price;
import domain.repro.Repro;
import domain.repro.ReproMisc;
import domain.result.Result;
import functions.Functions;

/**
 * Servlet implementation class Inputs
 */
//@WebServlet("/Inputs")
public class Inputs extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private FileSvc fileSvc = new FileSvc();
	private ResultSvc resultSvc = new ResultSvc();
	private MiscSvc miscSvc = new MiscSvc();
	private ReproSvc reproSvc = new ReproSvc();
	private PriceSvc priceSvc = new PriceSvc();
	private MilkSvc milkSvc = new MilkSvc();
	private CullSvc cullSvc = new CullSvc();
	private BWSvc bwSvc = new BWSvc();
	private Functions funSvc = new Functions();
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Inputs() {
        super();
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	response.setContentType("text/html");
		HttpSession session = request.getSession(false);
		if (session == null) {
			// No Existing Session Found Please Login Again
		}
		
		String servletPath = request.getServletPath();
		System.out.println("Servlet Path: "+servletPath);
		
		int userId = (Integer) session.getAttribute(Constants.SESSION_USER_ID);
		System.out.println(userId);
		
		int fileNo = 0;
		if(!servletPath.equals("/jsp/editScenario")){
			String fileNo_str = (String)session.getAttribute("fileNo");
			if (fileNo_str!=null) {
				fileNo = Utility.parseInt(fileNo_str);
			}else{
				// Error Page should be displayed
			}
		}
		
		
		
		if(servletPath.equals("/jsp/editScenario")){
			System.out.println("ScenId to Edit: "+request.getParameter("deleteScenarioId"));
			String fileNo_str=request.getParameter("deleteScenarioId");
			
			if(fileNo_str!=null){
				fileNo = Utility.parseInt(fileNo_str);
				session.setAttribute("fileNo", fileNo_str);
				
				Misc misc=miscSvc.getMiscDetails(fileNo);
				
				Repro repro=reproSvc.getReproDetails(fileNo);
				ReproMisc repromisc=repro.getMisc();
				
				session.setAttribute("unit", misc.getUnit());
				request.setAttribute("misc", misc);
				request.setAttribute("repromisc",repromisc);
				request.getRequestDispatcher("/jsp/input1_misc.jsp").forward(request, response);	
				
			}
		}else if(servletPath.equals("/jsp/inputMisc")){
			Misc misc=miscSvc.getMiscDetails(fileNo);
			Repro repro=reproSvc.getReproDetails(fileNo);
			ReproMisc repromisc=repro.getMisc();
			request.setAttribute("misc", misc);
			request.setAttribute("repromisc",repromisc);
			request.getRequestDispatcher("/jsp/input1_misc.jsp").forward(request, response);
			
		}else if(servletPath.equals("/jsp/saveMisc")){
			boolean saveSuccess = saveMisc(fileNo, request);
			if(saveSuccess){
				request.getRequestDispatcher("/jsp/operationcomplete.jsp").forward(request, response);	
			}else{
				// Error Page should be displayed
			}
			
		}else if(servletPath.equals("/jsp/saveAnalyzeMisc")){
			boolean saveSuccess = saveMisc(fileNo, request);
			if(saveSuccess){
				showResults(fileNo, request);
				request.getRequestDispatcher("/jsp/result.jsp").forward(request, response);
			}else{
				// Error Page should be displayed
			}
			
		}else if(servletPath.equals("/jsp/inputPrice")){
			Price price = priceSvc.getPriceDetails(fileNo);
			request.setAttribute("price", price);
			request.getRequestDispatcher("/jsp/input1_price.jsp").forward(request, response);
			
		}else if(servletPath.equals("/jsp/savePrice")){
			boolean saveSuccess = savePrice(fileNo, request);
			if(saveSuccess){
				request.getRequestDispatcher("/jsp/operationcomplete.jsp").forward(request, response);	
			}else{
				// Error Page should be displayed
			}
			
		}else if(servletPath.equals("/jsp/saveAnalyzePrice")){
			boolean saveSuccess = savePrice(fileNo, request);
			if(saveSuccess){
				showResults(fileNo, request);
				request.getRequestDispatcher("/jsp/result.jsp").forward(request, response);
			}else{
				// Error Page should be displayed
			}
			
		}else if(servletPath.equals("/jsp/inputMilk")){
			Milk milk = milkSvc.getMilkDetails(fileNo);
			request.setAttribute("milk", milk);
			request.getRequestDispatcher("/jsp/input1_milk.jsp").forward(request, response);
			
		}else if(servletPath.equals("/jsp/saveMilk")){
			boolean saveSuccess = saveMilk(fileNo, request);
			if(saveSuccess){
				request.getRequestDispatcher("/jsp/operationcomplete.jsp").forward(request, response);	
			}else{
				// Error Page should be displayed
			}
			
		}else if(servletPath.equals("/jsp/saveAnalyzeMilk")){
			boolean saveSuccess = saveMilk(fileNo, request);
			if(saveSuccess){
				showResults(fileNo, request);
				request.getRequestDispatcher("/jsp/result.jsp").forward(request, response);
			}else{
				// Error Page should be displayed
			}
			
		}else if(servletPath.equals("/jsp/inputCull")){
			Cull cull = cullSvc.getCullDetails(fileNo);
			request.setAttribute("cull", cull);
			request.getRequestDispatcher("/jsp/input1_cull.jsp").forward(request, response);
			
		}else if(servletPath.equals("/jsp/saveCull")){
			boolean saveSuccess = saveCull(fileNo, request);
			if(saveSuccess){
				request.getRequestDispatcher("/jsp/operationcomplete.jsp").forward(request, response);	
			}else{
				// Error Page should be displayed
			}
			
		}else if(servletPath.equals("/jsp/saveAnalyzeCull")){
			boolean saveSuccess = saveCull(fileNo, request);
			if(saveSuccess){
				showResults(fileNo, request);
				request.getRequestDispatcher("/jsp/result.jsp").forward(request, response);
			}else{
				// Error Page should be displayed
			}			
		}
		
		else if(servletPath.equals("/jsp/inputRepro")){
			Repro repro = reproSvc.getReproDetails(fileNo);
			request.setAttribute("repro", repro);
			request.getRequestDispatcher("/jsp/input1_repro.jsp").forward(request, response);
			
		}else if(servletPath.equals("/jsp/saveRepro")){
			boolean saveSuccess = saveRepro(fileNo, request);
			if(saveSuccess){
				request.getRequestDispatcher("/jsp/operationcomplete.jsp").forward(request, response);	
			}else{
				// Error Page should be displayed
			}
			
		}else if(servletPath.equals("/jsp/saveAnalyzeRepro")){
			boolean saveSuccess = saveCull(fileNo, request);
			if(saveSuccess){
				showResults(fileNo, request);
				request.getRequestDispatcher("/jsp/result.jsp").forward(request, response);
			}else{
				// Error Page should be displayed
			}
			
		}
		
		else if(servletPath.equals("/jsp/inputBW")){
			BodyWeightOpen bw = bwSvc.getBodyWeightOpen(fileNo);
			request.setAttribute("bw", bw);
			request.getRequestDispatcher("/jsp/input1_bw.jsp").forward(request, response);
			
		}else if(servletPath.equals("/jsp/saveBW")){
			boolean saveSuccess = saveBW(fileNo, request);
			if(saveSuccess){
				request.getRequestDispatcher("/jsp/operationcomplete.jsp").forward(request, response);	
			}else{
				// Error Page should be displayed
			}
			
		}else if(servletPath.equals("/jsp/saveAnalyzeBW")){
			boolean saveSuccess = saveBW(fileNo, request);
			if(saveSuccess){
				showResults(fileNo, request);
				request.getRequestDispatcher("/jsp/result.jsp").forward(request, response);
			}else{
				// Error Page should be displayed
			}			
		}
		
			
	}
    
    private boolean saveMisc(int fileNo, HttpServletRequest request){
    	/**
		 * We need to reset the Analyzed Flag here
		 */
		resultSvc.updateFileStatus(fileNo, Constants.NOT_ANALYZED);
		
    	Misc misc = new Misc();
    	ReproMisc repromisc=new ReproMisc();
    	
		double unit = Utility.parseDouble(request.getParameter("units"));
		System.out.println("Unit: "+unit);
		if(unit == Constants.KG){
			misc.setUnit(Constants.KG);	
		}else{
			misc.setUnit(Constants.LBS);
		}
		misc.setP_calf(Utility.parseDouble(request.getParameter("p_calf")));
		misc.setP_fixed_other(Utility.parseDouble(request.getParameter("p_fixed_other")));
		misc.setP_other_dry(Utility.parseDouble(request.getParameter("p_other_dry")));
		misc.setP_other_lact(Utility.parseDouble(request.getParameter("p_other_lact")));
		
		misc.getVetcost()[1] = Utility.parseDouble(request.getParameter("vetcost1"));
		misc.getVetcost()[2] = Utility.parseDouble(request.getParameter("vetcost2"));
		misc.getVetcost()[3] = Utility.parseDouble(request.getParameter("vetcost3"));
		misc.getVetcost()[4] = Utility.parseDouble(request.getParameter("vetcost4"));
		
		misc.setP_tmrdmdry(Utility.parseDouble(request.getParameter("p_tmrdmdry")));
		misc.setP_tmrdmlac(Utility.parseDouble(request.getParameter("p_tmrdmlac")));
		misc.setDmi_dry(Utility.parseDouble(request.getParameter("dmi_dry")));
		
		repromisc.setP_semen(Utility.parseDouble(request.getParameter("p_semen")));
		
		return (miscSvc.updateMiscDetails(fileNo, misc)&&reproSvc.updateReproMisc(fileNo, repromisc));
    }
    
    private boolean savePrice(int fileNo, HttpServletRequest request){
    	/**
		 * We need to reset the Analyzed Flag here
		 */
		resultSvc.updateFileStatus(fileNo, Constants.NOT_ANALYZED);
		
		Price price = priceSvc.getPriceDetails(fileNo);
		for(int i=1; i<=12; i++){
			price.getP_heifer()[i] = Utility.parseDouble(request.getParameter("heifer"+i));
			price.getP_heifer()[i+12] = Utility.parseDouble(request.getParameter("heifer"+i));
			
			price.getP_bodyweight()[i] = Utility.parseDouble(request.getParameter("cull"+i));
			price.getP_bodyweight()[i+12] = Utility.parseDouble(request.getParameter("cull"+i));
			
			price.getP_milk()[i] = Utility.parseDouble(request.getParameter("milk"+i));
			price.getP_milk()[i+12] = Utility.parseDouble(request.getParameter("milk"+i));
		}
		return priceSvc.updatePriceDetails(fileNo, price);
    }
    
    private boolean saveMilk(int fileNo, HttpServletRequest request){
    	/**
		 * We need to reset the Analyzed Flag here
		 */
		resultSvc.updateFileStatus(fileNo, Constants.NOT_ANALYZED);
		
    	Milk milk = new Milk();
    	int lact = 1;
    	for(lact=1; lact<=3; lact++){
			milk.getSeasonalityMilk().getAbsAdjustment()[lact] = Utility.parseDouble(request.getParameter("mabs"+lact));
			milk.getSeasonalityMilk().getPctAdjustment()[lact] = Utility.parseDouble(request.getParameter("pct"+lact))/100;
			milk.getSeasonalityMilk().getOverallSeasonality()[lact] = 1;		// Always 100 % (Not present on screen)
			for(int sea=1; sea<=12; sea++){
				milk.getSeasonalityMilk().getMonthlySeasonality()[lact][sea] = Utility.parseDouble(request.getParameter("msea"+lact+"_"+sea))/100;
			}
    	}
		
    	for(lact=1; lact<=3; lact++){
    		milk.getWoodCurves().getLactA()[lact] = Utility.parseDouble(request.getParameter("wood"+lact+"a"));
    		milk.getWoodCurves().getLactB()[lact] = Utility.parseDouble(request.getParameter("wood"+lact+"b"));
    		milk.getWoodCurves().getLactC()[lact] = Utility.parseDouble(request.getParameter("wood"+lact+"c"))/100;
    	}
		return milkSvc.updateMilkDetails(fileNo, milk);
    }
    
    private boolean saveCull(int fileNo, HttpServletRequest request){
    	/**
		 * We need to reset the Analyzed Flag here
		 */
		resultSvc.updateFileStatus(fileNo, Constants.NOT_ANALYZED);
		
    	Cull cull = new Cull();
    	cull.getSeasonalityCull().setAbsAdjustment(Utility.parseDouble(request.getParameter("cullabs")));
    	cull.getSeasonalityCull().setPctAdjustment(Utility.parseDouble(request.getParameter("cullpct"))/100);
    	cull.getSeasonalityCull().setOverallSeasonality(1);		// Always 100 % (Not present on screen)
		for(int sea=1; sea<=12; sea++){
			cull.getSeasonalityCull().getMonthlySeasonality()[sea] = Utility.parseDouble(request.getParameter("cullsea"+sea))/100;
		}
		
		for(int mim=1; mim<=24; mim++) {
			cull.getCullRiskMim()[mim] = Utility.parseDouble(request.getParameter("cullmim"+mim)) / 100;
		}
		
		for(int lact=1; lact<=12; lact++) {
			cull.getCullRiskLact()[lact] = Utility.parseDouble(request.getParameter("culllact"+lact)) / 100;
		}
		
		return cullSvc.updateCullDetails(fileNo, cull);
    }
    
    private boolean saveBW(int fileNo, HttpServletRequest request){
    	/**
		 * We need to reset the Analyzed Flag here
		 */
		resultSvc.updateFileStatus(fileNo, Constants.NOT_ANALYZED);
		
    	BodyWeightOpen bw = new BodyWeightOpen();
    	for(int lact=1; lact<=2; lact++){
    		System.out.println("Abs Adjustment: "+request.getParameter("bwAbs"+lact));
    		System.out.println("Pct Adjustment: "+request.getParameter("bwPct"+lact));
    		bw.getAbsAdjustment()[lact] = Utility.parseDouble(request.getParameter("bwAbs"+lact));
    		bw.getPctAdjustment()[lact] = Utility.parseDouble(request.getParameter("bwPct"+lact))/100;
    		for(int mim=1; mim<=Constants.MIM; mim++){
    			System.out.println("Lact: "+lact+" MIM: "+mim+" --> "+request.getParameter("bw"+lact+"_"+mim));
    			bw.getBodyWeightOpen()[lact][mim] = Utility.parseDouble(request.getParameter("bw"+lact+"_"+mim));
    		}
    	}
		
		return bwSvc.updateBodyWeightOpen(fileNo, bw);
    }
    
    private void showResults(int fileNo, HttpServletRequest request){
    	FileDetails defFile = fileSvc.getDefaultFile();
    	int fileNoA = defFile.getFileNo();
		int fileNoB = fileNo;
		
		if(defFile.getAnalyzed()==Constants.ANALYZED){
			funSvc.startSimulation(fileNoA);
		}
		funSvc.startSimulation(fileNoB);	
		
		Result resultA = resultSvc.getResult(fileNoA);
		Result resultB = resultSvc.getResult(fileNoB);
		
		request.setAttribute("resultA", resultA);
		request.setAttribute("resultB", resultB);
    }

    private boolean saveRepro(int fileNo, HttpServletRequest request){
    	
    	/**
		 * We need to reset the Analyzed Flag here
		 */
		resultSvc.updateFileStatus(fileNo, Constants.NOT_ANALYZED);
		
		ReproMisc repromisc=new ReproMisc();
    
    	return reproSvc.updateReproMisc(fileNo, repromisc);
    }
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request,response);
	}

}
